package ntu.sna;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.collections15.Factory;

import edu.uci.ics.jung.graph.Graph;

public class LifeController {
	private Factory<MyNode> nodeFactory;
	private int timeForFinalIteration;
	
	public LifeController(Factory<MyNode> vFactory, int timeForFinalIteration){
		this.nodeFactory = vFactory;
		this.timeForFinalIteration = timeForFinalIteration;
	}
	
	public Collection<MyNode> getInitialNodes(int numOfNodes){
		ArrayList<MyNode> nodeList = new ArrayList<MyNode>();
		for(int i = 0; i < numOfNodes; i++){
			MyNode node = nodeFactory.create(); //the life of the node is decided when creating it
			while(node.getRemainLife() == 0){
				node = nodeFactory.create();
			}
			nodeList.add(node);
		}
		return nodeList;
	}
	
	public Collection<MyNode> getNodesToRemoveAtTime(Graph<MyNode, MyLink> graph, int time){
		Collection<MyNode> nodeCollect = graph.getVertices();
		Iterator<MyNode> nodeIterator = nodeCollect.iterator();
		Collection<MyNode> nodesToRemove = new ArrayList<MyNode>();
		//remove nodes with remainLife = 0 and subtract other nodes' remainLife by 1
		while(nodeIterator.hasNext()){
			MyNode node = nodeIterator.next();
			if(node.getRemainLife() == 0){
				nodesToRemove.add(node);
			}else{
				node.setRemainLife(node.getRemainLife() - 1);
			}
		}
		return nodesToRemove;
	}
	
	public Collection<MyNode> getNodesToAddAtTime(Graph<MyNode, MyLink> graph, int time){
		int numOfNodes = graph.getVertexCount();
		Collection<MyNode> nodesToAdd = new ArrayList<MyNode>();
		if(time < timeForFinalIteration - 99){
			for(int i = 0; i < (int)(numOfNodes * 0.015); i++){
				nodesToAdd.add(nodeFactory.create());
			}
		}else{
			int countDown = timeForFinalIteration - time;
			double ratioOverAge = 0;
			for(int i = countDown; i < 100; i++){
				ratioOverAge += LifeGenerator.getLifeDisTW(i);
			}
			int numOfBirth = (int)(10000 * LifeGenerator.getAgeDisTW(countDown) / ratioOverAge);
			for(int i = 0; i < numOfBirth; i++){
				nodesToAdd.add(nodeFactory.create());
			}
		}
		return nodesToAdd;
	}
}
